package org.boot.easyapi.core.util.sql;

import lombok.extern.slf4j.Slf4j;
import org.boot.easyapi.pojo.auto.AuthenticationUserInfo;
import org.boot.easyapi.util.CollUtil;
import org.boot.easyapi.util.ObjectUtil;
import org.boot.easyapi.util.StrUtil;
import org.boot.easyapi.util.id.EasyApiSnowFlakeIdWorker8910;
import org.boot.easyapi.util.id.EasyApiSnowflakeIdWorker14;
import org.boot.easyapi.util.web.AuthenticationUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

import static org.boot.easyapi.core.framework.IdGenera.EasyApiIdGeneraConfig.*;
import static org.boot.easyapi.core.framework.IdGenera.EasyApiIdGeneraConfig.ID_AUTO;
import static org.boot.easyapi.core.service.table.impl.TableServiceImpl.defaultFields;

@Slf4j
@Component
public class DefaultSqlOperationUtil {

    @Value("${easyapi.table.app.id-generator:ID_SNOWFLAKE_14}")
    private String idGeneraType;

    @Value("${easyapi.table.app.deleted-logic:true}")
    private boolean deletedLogic;

    @Value("${easyapi.api.tenant-enable:true}")
    private boolean tenantEnabled;

    @Value("${easyapi.api.only-camel-case:true}")
    private boolean onlyCamelCase;



    @Lazy
    @Resource(name = "easyapi-easyApiSnowflakeIdWorker14")
    private EasyApiSnowflakeIdWorker14 easyApiSnowflakeIdWorker14;

    @Lazy
    @Resource(name = "easyapi-easyApiSnowFlakeIdWorker8910")
    private EasyApiSnowFlakeIdWorker8910 easyApiSnowFlakeIdWorker8910;


    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~默认插入的字段~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·~~~~~~~~~~~~~~~~~~//
    private final static List<String> DEFAULT_AUTO_INSERT_COLUMNS = Collections.unmodifiableList(Arrays.asList(
            "creator", "create_time", "updater", "update_time", "deleted", "tenant_id"
    ));
    private final static List<String> DEFAULT_INSERT_COLUMNS = Collections.unmodifiableList(Arrays.asList(
            "id, creator", "create_time", "updater", "update_time", "deleted", "tenant_id"
    ));


    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~insert~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·~~~~~~~~~~~~~~~~~~//
    /**
     * 调整系统表默认字段：字段名/字段值
     * @param colValMap
     * @return
     */
    public Map<String, Object> insertDefaultColValMap(Map<String, Object> colValMap){

        //先映射驼峰
        if(onlyCamelCase){
            colValMap = MappingConvertUtil.mappingFiled(colValMap);
        }

        //移除默认字段
        List<String> removeColValMap = new ArrayList<>();
        for (String key : colValMap.keySet()) {
            if(defaultFields.containsKey(key)){
                removeColValMap.add(key);
            }
        }
        if(CollUtil.isNotEmpty(removeColValMap)){
            colValMap.keySet().removeAll(removeColValMap);
        }

        //添加默认字段：字段名/字段值
        colValMap.putAll(insertDefaultInsertColumns());
        return colValMap;
    }

    public List<Map<String, Object>> insertDefaultColValMap(List<Map<String, Object>> colValMap){
        List<Map<String, Object>> colValMapList = new ArrayList<>();
        for (Map<String, Object> map : colValMap) {
            colValMapList.add(insertDefaultColValMap(map));
        }
        return colValMapList;
    }

    /**
     * 添加默认字段：字段名/字段值
     * @return
     */
    private Map<String, Object> insertDefaultInsertColumns(){
        Map<String, Object> colValMap = new HashMap<>();

        //添加默认字段：字段名/字段值
        if(idGeneraType.equals(ID_SNOWFLAKE_14)){
            colValMap.put("id", easyApiSnowflakeIdWorker14.nextId());
        }else if(idGeneraType.equals(ID_SNOWFLAKE_8910)){
            colValMap.put("id", easyApiSnowFlakeIdWorker8910.nextId());
        }
        Object username = AuthenticationUtil.getAuthenticationUserInfo().getUsername();
        String tenantId = AuthenticationUtil.getAuthenticationUserInfo().getTenantId();
        if(ObjectUtil.isNotEmpty(username)){
            colValMap.put("creator", username);
            colValMap.put("updater", username);
        }
        if(StrUtil.isNotEmpty(tenantId)){
            colValMap.put("tenant_id", tenantId);
        }
        colValMap.put("create_time", LocalDateTime.now());
        colValMap.put("update_time", LocalDateTime.now());
        colValMap.put("deleted", 0);

        return colValMap;
    }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~insert~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·~~~~~~~~~~~~~~~~~~//
    /**
     * 调整系统表默认字段：字段名/字段值
     * @param colValMap
     * @return
     */
    public Map<String, Object> updateDefaultColValMap(Map<String, Object> colValMap){
        //先映射驼峰
        if(onlyCamelCase){
            colValMap = MappingConvertUtil.mappingFiled(colValMap);
        }

        //移除默认字段
        List<String> removeColValMap = new ArrayList<>();
        for (String key : colValMap.keySet()) {
            if(defaultFields.containsKey(key)){
                removeColValMap.add(key);
            }
        }
        if(CollUtil.isNotEmpty(removeColValMap)){
            colValMap.keySet().removeAll(removeColValMap);
        }

        //添加默认字段：字段名/字段值
        colValMap.putAll(updateDefaultInsertColumns());
        return colValMap;
    }

    public List<Map<String, Object>> updateDefaultColValMap(List<Map<String, Object>> colValMap){
        List<Map<String, Object>> colValMapList = new ArrayList<>();
        for (Map<String, Object> map : colValMap) {
            colValMapList.add(updateDefaultColValMap(map));
        }
        return colValMapList;
    }

    /**
     * 添加默认字段：字段名/字段值
     * @return
     */
    private Map<String, Object> updateDefaultInsertColumns(){
        Map<String, Object> colValMap = new HashMap<>();
        //添加默认字段：字段名/字段值
        Object username = AuthenticationUtil.getAuthenticationUserInfo().getUsername();
        if (ObjectUtil.isNotEmpty(username)) {
            colValMap.put("updater", username);
        }
        colValMap.put("update_time", LocalDateTime.now());
        return colValMap;
    }


    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~默认插入的值~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·~~~~~~~~~~~~~~~~~~//
    // insert - 默认values
    private String defaultInsertValuesSql(){
        AuthenticationUserInfo userInfo = AuthenticationUtil.getAuthenticationUserInfo();
        List<String> values = Arrays.asList(
                "'"+genNextId()+"'", "'"+userInfo.getUsername()+"'", "'"+ LocalDateTime.now()+"'",
                "'"+userInfo.getUsername()+"'", "'"+LocalDateTime.now()+"'", "0", "'"+userInfo.getTenantId()+"'"
        );
        return convertListToFieldSql(values);
    }

    // insert(自增) - 默认values
    private String defaultAutoInsertValuesSql(){
        AuthenticationUserInfo userInfo = AuthenticationUtil.getAuthenticationUserInfo();
        List<String> values = Arrays.asList(
                "'"+userInfo.getUsername()+"'", "'"+LocalDateTime.now()+"'",
                "'"+userInfo.getUsername()+"'", "'"+LocalDateTime.now()+"'", "0", "'"+userInfo.getTenantId()+"'"
        );
        return convertListToFieldSql(values);
    }

    // update - 默认字段/values
    private String defaultUpdateValuesSql(){
        Object username = AuthenticationUtil.getAuthenticationUserInfo().getUsername();
        if (ObjectUtil.isNotEmpty(username)) {
            return " updater = '" + username +"', update_time = '" + LocalDateTime.now()+"' ";
        }
        return " update_time = '" + LocalDateTime.now()+"' ";
    }

    /**
     * 生成下一个主键ID
     * @return
     */
    public Long genNextId(){
        if(idGeneraType.equals(ID_SNOWFLAKE_14)){
            return easyApiSnowflakeIdWorker14.nextId();
        }else if(idGeneraType.equals(ID_SNOWFLAKE_8910)){
            return easyApiSnowFlakeIdWorker8910.nextId();
        }
        return easyApiSnowflakeIdWorker14.nextId();
    }

    /**
     * 将字段列表转换为 SQL 字段字符串
     * @param fieldList 字段列表
     * @return SQL 字段字符串
     * ## 示例
     * [id, creator, create_time, updater, update_time, deleted, tenant_id]
     * --->
     * id, creator, create_time, updater, update_time, deleted, tenant_id
     */
    private static String convertListToFieldSql(List<String> fieldList){
        return String.join(", ", fieldList);
    }

    /**
     * 系统表：insert - 默认插入的字段
     * @return
     */
    public String defaultInsertColumns(){
        if(idGeneraType.equals(ID_AUTO)){
            return convertListToFieldSql(DEFAULT_AUTO_INSERT_COLUMNS);
        }else if(idGeneraType.equals(ID_SNOWFLAKE_8910)
                || idGeneraType.equals(ID_SNOWFLAKE_14)
        ){
            return convertListToFieldSql(DEFAULT_INSERT_COLUMNS);
        }
        return convertListToFieldSql(DEFAULT_INSERT_COLUMNS);
    }

    /**
     * 系统表：insert - 默认插入的值
     * @return
     */
    public String defaultInsertValues(){
        if(idGeneraType.equals(ID_AUTO)) return defaultAutoInsertValuesSql();
        return defaultInsertValuesSql();
    }


    /**
     * 系统表：update - 默认更新的字段/值
     * @return
     */
    public String defaultUpdateSet(){
        return defaultUpdateValuesSql();
    }

    /**
     * 系统表：delete - 默认逻辑/删除的sql
     * @param tableName
     * @return
     */
    public String defaultDeleted(String tableName){
        if(!deletedLogic){
            return " DELETE FROM " + tableName + " ";
        }else {
            return " UPDATE " + tableName + " SET deleted = 1, " + defaultUpdateValuesSql();
        }
    }

}
